package cn.zyx.common.utils.file;

import cn.zyx.common.GlobalExceptions;
import cn.zyx.common.utils.sys.IdGenUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 水印工具类
 */
public class WaterMarkUtils {

    /**
     * @param srcImgPath     场景图片地址-后置摄像头
     * @param srcImgPathUser 人员图片地址-前置摄像头
     * @param tarImgPath     保存的图片路径
     * @param list           水印内容
     */
    public static File addWaterMark(String srcImgPath, String srcImgPathUser, String tarImgPath, List<String> list) {
        try {
            // 方式二：读取远程的原图片信息
            URL srcImgFile = new URL(srcImgPath);
            Image srcImg = ImageIO.read(srcImgFile);//文件转化为图片
            if (StringUtils.isBlank(tarImgPath)) {
                tarImgPath = IdGenUtils.simpleUuid() + ".jpg";
            }
            if (StringUtils.isNotBlank(srcImgPathUser)) {
                URL srcImgFileUser = new URL(srcImgPathUser);
                Image srcImgUser = ImageIO.read(srcImgFileUser);//文件转化为图片
                File file = setFile(srcImg, srcImgUser, list, tarImgPath);
                return file;
            } else {
                File file = setFile(srcImg, null, list, tarImgPath);
                return file;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            new GlobalExceptions("图片获取异常！");
        }
        return null;
    }

    /**
     * 添加水印
     *
     * @param srcImgPath
     * @param srcImgPathUser
     * @param tarImgPath
     * @param list
     * @return
     */
    public static File addWaterMark(MultipartFile srcImgPath, MultipartFile srcImgPathUser, String tarImgPath, List<String> list) {

        try {
            // 方式二：读取远程的原图片信息
            Image srcImg = ImageIO.read(srcImgPath.getInputStream());//文件转化为图片
            if (StringUtils.isBlank(tarImgPath)) {
                tarImgPath = IdGenUtils.simpleUuid() + ".jpg";
            }
            if (ObjectUtils.isNotEmpty(srcImgPathUser)) {
                Image srcImgUser = ImageIO.read(srcImgPathUser.getInputStream());//文件转化为图片
                File file = setFile(srcImg, srcImgUser, list, tarImgPath);
                return file;
            } else {
                File file = setFile(srcImg, null, list, tarImgPath);
                return file;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return null;
    }

    public static File setFile(Image srcImg, Image srcImgUser, List<String> list, String tarImgPath) {
        try {
            // 方式一：读取本地的原图片信息
            // File srcImgFile = new File(srcImgPath);//得到文件
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);

            // 方式二：读取远程的原图片信息

            //固定背景图片的长宽
            int srcImgWidth = 1280;//获取图片的宽
            int srcImgHeight = 1707;//获取图片的高
            if (imgWidth > imgHeight) {
                srcImgWidth = 1707;//获取图片的宽
                srcImgHeight = 1280;//获取图片的高
            }

            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight + 260, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);

            Color color = new Color(115, 114, 114, 153);
            g.setColor(color);
            g.fillRect(0, srcImgHeight, srcImgWidth, 260);

            Color markContentColor = new Color(250, 249, 249, 255);
            g.setStroke(new BasicStroke());
            g.setColor(markContentColor); //根据图片的背景设置水印颜色
            Font font = new Font("宋体", Font.BOLD, 26);
            g.setFont(font);              //设置字体

            //设置水印的坐标
            int x = 30;
            int y = srcImgHeight + 50;

//            g.drawString(waterMarkContent, x, y);  //画出水印
            for (int i = 0; i < list.size(); i++) {
                if (i > 0) {
                    int strHeight = getStringHeight(g);
                    y = y + strHeight + 6;
                    font = new Font("宋体", Font.PLAIN, 24);
                }
                y = drawStringWithFontStyleLineFeed(g, list.get(i), x, y, font);
                y += 6;
            }

            g.setStroke(new BasicStroke());
            g.setColor(markContentColor);
            Font fontSize = new Font("宋体", Font.BOLD, 14);
            g.setFont(fontSize);
            //直接绘制
            // TODO: 2024-01-17 preventId 防伪ID，后续上传区块链，先用uuid
            String preventId = IdGenUtils.simpleUuid();
            g.drawString("防伪id：" + preventId, 10, 20);
            g.fillRect(0, 180 + y, 500, srcImgHeight);
            g.setColor(markContentColor); //根据图片的背景设置水印颜色
            g.setFont(font);
            if (ObjectUtils.isNotEmpty(srcImgUser)) {
                int imgWidthUser = srcImgUser.getWidth(null);
                int imgHeightUser = srcImgUser.getHeight(null);

                int srcImgWidthUser = 260;//获取图片的宽
                int srcImgHeightUser = 300;//获取图片的高
                if (imgWidthUser > imgHeightUser) {
                    srcImgWidthUser = 300;//获取图片的宽
                    srcImgHeightUser = 260;//获取图片的高
                }

                g.drawImage(srcImgUser, srcImgWidth - 260, srcImgHeight, srcImgWidthUser, srcImgHeightUser, null);
                g.dispose();
            }

            // 第一种：输出图片到本地
//            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
//            ImageIO.write(bufImg, "jpg", outImgStream);
//            System.out.println("添加水印完成");
//            outImgStream.flush();
//            outImgStream.close();
            if (StringUtils.isBlank(tarImgPath)) {
                tarImgPath = IdGenUtils.simpleUuid() + ".jpg";
            }
            // 第二种：输出图片到远程（借助自己的远程上传工具）
            File localFile = new File(tarImgPath);//得到文件
            ImageIO.write(bufImg, "jpg", localFile);
            return localFile;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            new GlobalExceptions("图片合成异常！");
        }
        return null;
    }

    public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

    //字符串总宽度
    private static int getStringLength(Graphics g, String str) {
        char[] strcha = str.toCharArray();
        int strWidth = g.getFontMetrics().charsWidth(strcha, 0, str.length());
        return strWidth;
    }


//        //每一行字符串宽度  自定义  也就是画布中一行的宽度
//        int rowWidth=1110;
//        //字符串字符的个数
//        int strnum= str.length();
//        //每一行字符的个数

    private static int getRowStrNum(int strnum, int rowWidth, int strWidth) {
        int rowstrnum = 0;
        rowstrnum = (rowWidth * strnum) / strWidth;
        return rowstrnum;
    }

    //字符行数
    private static int getRows(int strWidth, int rowWidth) {
        int rows = 0;
        if (strWidth % rowWidth > 0) {
            rows = strWidth / rowWidth + 1;
        } else {
            rows = strWidth / rowWidth;
        }
        return rows;
    }

    //字符高度
    private static int getStringHeight(Graphics g) {
        int height = g.getFontMetrics().getHeight();
        return height;
    }

    private static int drawStringWithFontStyleLineFeed(Graphics2D g, String strContent, int loc_X, int loc_Y, Font font) {
        g.setFont(font);

        //获取字符串 字符的总宽度
        int strWidth = getStringLength(g, strContent);

        //每一行字符串宽度
        int rowWidth = 700;

        //获取字符高度
        int strHeight = getStringHeight(g);

        //字符串总个数
        if (strWidth > rowWidth) {

            int rowstrnum = getRowStrNum(strContent.length(), rowWidth, strWidth);
            int rows = getRows(strWidth, rowWidth);

            String temp = "";
            for (int i = 0; i < rows; i++) {
                //获取各行的String
                if (i == rows - 1) {
                    //最后一行
                    temp = strContent.substring(i * rowstrnum, strContent.length());
                } else {
                    temp = strContent.substring(i * rowstrnum, i * rowstrnum + rowstrnum);
                }
                if (i > 0) {
                    //第一行不需要增加字符高度，以后的每一行在换行的时候都需要增加字符高度
                    loc_Y = loc_Y + strHeight + 10;
                }
                g.drawString(temp, loc_X, loc_Y);
            }
        } else {
            //直接绘制
            g.drawString(strContent, loc_X, loc_Y);
        }
        return loc_Y;
    }

    public static void main1(String[] args) {
        Font font = new Font("宋体", Font.BOLD, 35);                     //水印字体
        String srcImgPath = "https://esa.test.wdtszkj.com/hbzhscjg/MCLZ/minio/esa-bucket/test/2024/01/17/backImg_20240117105823A001.jpg"; //源图片地址
        String srcImgPathUser = "https://esa.test.wdtszkj.com/hbzhscjg/MCLZ/minio/esa-bucket/test/2024/01/17/peopleImg_20240117105847A002.jpg"; //人脸图片地址
        String tarImgPath = "D:\\tmp\\200_2010.jpg"; //待存储的地址
        List<String> list = new ArrayList<>();
        list.add("施工现场打开记录");
        list.add("地址：湖北省武汉市江汉区");
        list.add("时间：" + LocalDateTime.now());
        list.add("张三：130****512");
        Color color = new Color(113, 113, 114, 205);                               //水印图片色彩以及透明度
        WaterMarkUtils.addWaterMark(srcImgPath, srcImgPathUser, tarImgPath, list);
    }

    public static void main(String[] args) {
        // 方式二：读取远程的原图片信息
        String srcImgPath = "C:\\Users\\13387\\Desktop\\导出临时文件\\测试图片.jpg";
        String tarImgPath = "C:\\Users\\13387\\Desktop\\导出临时文件\\武汉中晶11.png";
        String remark = "湖北武汉黄陂";
        try {
//            URL srcImgFile = new URL(srcImgPath);
            File file = new File(srcImgPath);
            Image srcImg = ImageIO.read(file);//文件转化为图片
            File file1 = WaterMarkUtils.setFile(srcImg, null, Arrays.asList(remark), tarImgPath);
//            if (ObjectUtil.isNotEmpty(file) && file.exists()) {
//                file.delete();
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
